{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "9b3f9a49-79cb-4028-8440-a331dafcc40a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import torch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "29883ae9-bc2b-4612-91ef-5215d9a8c645",
   "metadata": {},
   "outputs": [],
   "source": [
    "N = 20\n",
    "X = torch.rand(N)  # 生成n个随机数,0-1\n",
    "k = 2\n",
    "b = 3\n",
    "Y = k * X + b + torch.randn(N) * 0.02  # 噪声用randn，正态分布"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "0b2d686d-aff1-40e0-8e6c-34a7e0fd01b1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x1b58bc21ac0>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X, Y)  # 快速画图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "ca2bb4de-21db-4f26-ac9e-fb43baa273d8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([0.4969], requires_grad=True), tensor([0.7788], requires_grad=True))"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w_k = torch.rand(1)\n",
    "w_k.requires_grad = True\n",
    "w_b = torch.rand(1)\n",
    "w_b.requires_grad = True\n",
    "w_k, w_b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d11ded1d-af78-43fe-8f45-8c4443a92376",
   "metadata": {},
   "outputs": [],
   "source": [
    "lr = 0.02"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "8e79d237-c64a-4a10-8b84-a245c965c31a",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(1000):\n",
    "    # calc y_hat\n",
    "    y_hat = w_k * X + w_b\n",
    "    # calc loss\n",
    "    loss = ((y_hat - Y)**2).mean()  # 求数组平均值\n",
    "    # backward, update grad\n",
    "    loss.backward()\n",
    "    # update w_k, w_b\n",
    "    w_k.data = w_k.data - lr * w_k.grad.data\n",
    "    w_b.data = w_b.data - lr * w_b.grad.data\n",
    "    # clear grad\n",
    "    w_b.grad.data = torch.zeros(1)\n",
    "    w_k.grad.data = torch.zeros(1)\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "d4f7c4f3-5d68-4d51-97a9-d783c894e3c9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x1b58bd6bfd0>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "test_x = torch.linspace(0, 1, 100)\n",
    "test_y = test_x * w_k.detach() + w_b.detach()  # .detach() == .data\n",
    "plt.plot(test_x, test_y)\n",
    "plt.scatter(X, Y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "02b0bc27-bb22-4872-85a1-af12f0e6aa48",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([1.9757]), tensor([3.0053]))"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w_k.data, w_b.data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "cfbf84a8-defb-460d-bcaa-02b1a7c181a7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([0.]), tensor([0.]))"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w_k.grad, w_b.grad"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
